package br.com.divulgaqui.managedbean;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

import br.com.divulgaqui.client.CategoriaServiceBeanLocal;
import br.com.divulgaqui.client.exception.EntityIgualException;
import br.com.divulgaqui.entity.Categoria;

import com.ocpsoft.pretty.faces.annotation.URLAction;
import com.ocpsoft.pretty.faces.annotation.URLMapping;
import com.ocpsoft.pretty.faces.annotation.URLMappings;

@ManagedBean
@ViewScoped
@URLMappings(mappings={
		  @URLMapping(id = "cadastroCategoria", pattern = "/admin/categoria/cadastro", viewId = "/admin/categoria/cadastro.jsf"),
		  @URLMapping(id = "atualizacaoCategoria", pattern = "/admin/categoria/atualizacao", viewId = "/admin/categoria/atualizacao.jsf"),
		  @URLMapping(id = "ativacaoCategoria", pattern = "/admin/categoria/ativacao", viewId = "/admin/categoria/ativacao.jsf")
		})
public class CategoriaManagedBean extends BaseBean{
	
	private static final long serialVersionUID = 1L;
	private Categoria categoria;
	private Categoria catParente;
	private Categoria subParente;
	private Categoria categoriaSelecionada;
	private Categoria catParenteSelecionada;
	private Categoria subParenteSelecionada;
	private List<Categoria> categorias;
	private List<Categoria> catsParentes;
	private List<Categoria> subsParentes;
	private List<Categoria> categoriasComplete;
	
	@EJB
	private CategoriaServiceBeanLocal categoriaServiceBeanLocal;
	
	public CategoriaManagedBean(){
	}
	
	@PostConstruct
	public void init(){
		categoria = new Categoria();
		catParente= new Categoria();
		subParente= new Categoria();
		categoriaSelecionada = new Categoria();
		catParenteSelecionada = new Categoria();
		subParenteSelecionada = new Categoria();
		categorias = new ArrayList<Categoria>();
		catsParentes = new ArrayList<Categoria>();
		subsParentes = new ArrayList<Categoria>();	
		categorias = categoriaServiceBeanLocal.listarCategorias();
	}		
	
	/**
	 * Inclui a categoria principal - sem parentes
	 */
	public void incluirNivel1(){	
		try {
			categoriaServiceBeanLocal.salvar(categoria);
		} catch (EntityIgualException e) {			
			addMensagem(FacesMessage.SEVERITY_ERROR, "Nível 1", "Categoria com nome \""+categoria.getNome()+"\" já foi cadastrada.");
			return;
		}
		categorias.add(categoria);
		carregarNivel1();
		catsParentes.clear();
		subsParentes.clear();
		categoria = new Categoria();	
		addMensagem(FacesMessage.SEVERITY_INFO, "Nível 1", "Categoria incluída com sucesso.");
	}
	
	/**
	 * Inclui a categoria parente
	 */
	public void incluirNivel2(){	
		if(categoriaSelecionada == null || categoriaSelecionada.getId() == null){
			addMensagem(FacesMessage.SEVERITY_ERROR, "Nível 2", "Selecione uma categoria no Nível 1.");
			return;
		}		
		try {
			//realcionando com a categoria principal
			catParente.setCatParente(categoriaSelecionada);
			categoriaServiceBeanLocal.salvar(catParente);
		} catch (EntityIgualException e) {			
			addMensagem(FacesMessage.SEVERITY_ERROR, "Nível 2", "Categoria com nome \""+catParente.getNome()+"\" já foi cadastrada.");
			return;
		}
		carregarNivel2();
		subsParentes.clear();
		catParente = new Categoria();	
		addMensagem(FacesMessage.SEVERITY_INFO, "Nível 2", "Categoria incluída com sucesso.");
	}
	
	/**
	 * Inclui a categoria subParente
	 */
	public void incluirNivel3(){
		if(catParenteSelecionada == null  || catParenteSelecionada.getId() == null){
			addMensagem(FacesMessage.SEVERITY_ERROR, "Nível 3", "Selecione uma categoria no Nível 2.");
			return;
		}		
		try {
			//relacionando com a parente	
			subParente.setCatParente(catParenteSelecionada);
			categoriaServiceBeanLocal.salvar(subParente);
		} catch (EntityIgualException e) {			
			addMensagem(FacesMessage.SEVERITY_ERROR, "Nível 3", "Categoria com nome \""+subParente.getNome()+"\" já foi cadastrada.");
			return;
		}
		carregarNivel3();
		subParente = new Categoria();
		addMensagem(FacesMessage.SEVERITY_INFO, "Nível 3", "Categoria incluída com sucesso.");
	}
	
	/**
	 * Atualiza a categoria do nível 1
	 */
	public void atualizarNivel1(){		
		try {			
			categoriaServiceBeanLocal.atualizar(categoriaSelecionada);
		} catch (EntityIgualException e) {			
			addMensagem(FacesMessage.SEVERITY_ERROR, "Nível 1", "Categoria com nome \""+categoriaSelecionada.getNome()+"\" já foi cadastrada.");
			return;
		}
		categorias = categoriaServiceBeanLocal.listarCategorias();
		if(!categoriaSelecionada.getAtivo()){
			categoriaSelecionada = new Categoria();
			catsParentes.clear();
			subsParentes.clear();
		}
		addMensagem(FacesMessage.SEVERITY_INFO, "Nível 1", "Categoria atualizada com sucesso.");
	}
	
	/**
	 * Atualiza a categoria do nível 2
	 */
	public void atualizarNivel2(){		
		try {			
			categoriaServiceBeanLocal.atualizar(catParenteSelecionada);
		} catch (EntityIgualException e) {			
			addMensagem(FacesMessage.SEVERITY_ERROR, "Nível 2", "Categoria com nome \""+catParenteSelecionada.getNome()+"\" já foi cadastrada.");
			return;
		}
		carregarNivel2();
		if(!catParenteSelecionada.getAtivo()){
			catParenteSelecionada = new Categoria();		
			subsParentes.clear();
		}
		addMensagem(FacesMessage.SEVERITY_INFO, "Nível 2", "Categoria atualizada com sucesso.");
	}
	
	/**
	 * Atualiza a categoria do nível 3
	 */
	public void atualizarNivel3(){		
		try {			
			categoriaServiceBeanLocal.atualizar(subParenteSelecionada);
		} catch (EntityIgualException e) {			
			addMensagem(FacesMessage.SEVERITY_ERROR, "Nível 3", "Categoria com nome \""+subParenteSelecionada.getNome()+"\" já foi cadastrada.");
			return;
		}
		carregarNivel3();
		if(!subParenteSelecionada.getAtivo()){
			subParenteSelecionada = new Categoria();				
		}
		addMensagem(FacesMessage.SEVERITY_INFO, "Nível 3", "Categoria atualizada com sucesso.");
	}	
	
	public void ativarNivel(){
		if(categoriaSelecionada == null){
			addMensagem(FacesMessage.SEVERITY_ERROR, "Categoria", "Selecione uma categoria.");
			return;
		}
		categoriaSelecionada.setAtivo(true);
		categoriaServiceBeanLocal.atualizar(categoriaSelecionada);
		carregarNivelInativo();
		addMensagem(FacesMessage.SEVERITY_INFO, "Categoria", "Categoria ativada com sucesso.");
	}
	
	/**
	 * Limpa lista de categoria do nível 2 e 3
	 */
	public void limparNivelDoisTres(){
		catsParentes.clear();
		subsParentes.clear();
	}
	
	/**
	 * Limpa lista de categoria do nível 3
	 */
	public void limparNivelTres(){		
		subsParentes.clear();
	}
	
	/**
	 * Carrega as categorias do nível 1
	 */
	public void carregarNivel1(){
		categorias = categoriaServiceBeanLocal.listarCategorias();
	}	
	
	/**
	 * Carrega as categorias parentes a partir da categoria principal selecionada
	 */
	public void carregarNivel2(){
		Long idParente = this.categoriaSelecionada.getId();
		subsParentes.clear();
		this.catsParentes = categoriaServiceBeanLocal.listarSubsParentes(idParente);	
	}
	
	/**
	 * Carrega as categorias subParentes a partir da categoria parente selecionada
	 */
	public void carregarNivel3(){
		Long idParente = this.catParenteSelecionada.getId();	
		this.subsParentes = categoriaServiceBeanLocal.listarSubsParentes(idParente);	
	}
	
	/**
	 * Carrega as categorias inativas
	 */
	@URLAction(mappingId = "ativacaoCategoria", onPostback=false)
	public void carregarNivelInativo(){	
		this.categorias = categoriaServiceBeanLocal.listarCategoriasInativas();
	}//TODO Vefiricar a chamada do método pela url e por @PostConstrutor
	
	/**
	 * Pesquisa as marcas que conferem com o texto informado
	 * e retorna a lista
	 * @param texto
	 * @return result
	 */
	public List<Categoria> complete(String texto){
		if(categoriasComplete == null){
			categoriasComplete = categoriaServiceBeanLocal.listarCategoriasNivel3();
		}
		List<Categoria> result = new ArrayList<Categoria>();		
		for (Categoria categoria : categoriasComplete) {
			if ((categoria.getNome() != null && categoria.getNome().toLowerCase()
					.indexOf(texto.toLowerCase()) == 0)
					|| "".equals(texto)) {
				result.add(categoria);
			}
		}
		return result;
	}

	//====================== Get e Set ====================//

	public Categoria getCategoria() {		
		return categoria;
	}

	public void setCategoria(Categoria categoria) {	
		this.categoria = categoria;
	}

	public List<Categoria> getCategorias() {	
		return this.categorias;
	}	

	public List<Categoria> getSubsParentes() {
		return subsParentes;
	}

	public void setSubsParentes(List<Categoria> subsParentes) {
		this.subsParentes = subsParentes;
	}

	public Categoria getCatParente() {
		return catParente;
	}

	public void setCatParente(Categoria catParente) {
		this.catParente = catParente;
	}

	public Categoria getSubParente() {
		return subParente;
	}

	public void setSubParente(Categoria subParente) {		
		this.subParente = subParente;
	}

	public List<Categoria> getCatsParentes() {
		return catsParentes;
	}

	public void setCatsParentes(List<Categoria> catsParentes) {
		this.catsParentes = catsParentes;
	}		

	public Categoria getCategoriaSelecionada() {
		return categoriaSelecionada;
	}

	public void setCategoriaSelecionada(Categoria categoriaSelecionada) {
		this.categoriaSelecionada = categoriaSelecionada;
	}

	public Categoria getCatParenteSelecionada() {
		return catParenteSelecionada;
	}

	public void setCatParenteSelecionada(Categoria catParenteSelecionada) {
		this.catParenteSelecionada = catParenteSelecionada;
	}

	public Categoria getSubParenteSelecionada() {
		return subParenteSelecionada;
	}

	public void setSubParenteSelecionada(Categoria subParenteSelecionada) {
		this.subParenteSelecionada = subParenteSelecionada;
	}
}
